import axios from 'axios'
import store from '@/store'
import router from '@/router'
import { sysAppId } from '@/settings.js'
import { default as expiresCalculation, getExpiresTime, minExpTime } from './expires'
import { Message } from 'element-ui'
import {getOperateTime, setOperateTime, getLogoutFlag, setLogoutFlag,removeLogoutFlag} from '../utils/auth.js'
// 处理请求数据 9101
const whiteList = [
  '/api/Jwt/tokensm2',
  '/api/Jwt/token',
  '/api/Jwt/RefreshAccessToken', // 更新token
  '/api/v1/mobileJwt/AccessTokenEncrypt', // 获取token
  '/api/Jwt/RefreshToken' // 令牌过期的token刷新
]
let isRefreshing = false // 控制登录过期的提示锁
let requests = [] // 缓存token刷新，需要重新发起的请求

const service = axios.create({
  baseURL: window.g.API_ROOT,
  timeout: window.g.AXIOS_TIMEOUT || 5000
})

service.interceptors.request.use(
  config => {
    // 请求拦截
    let operateTime = window.g.operateTime || 240
    let _path = router.history.current.path
    console.log('_path', _path)
    if(getOperateTime() && (new Date().getTime() - getOperateTime() > operateTime * 60 * 1000) && getOperateTime() != ''){
      // 判断是否从单点登录过来的
      if (_path == '/sm2login' || _path == '/logging' || _path == '/dlogin') {
        // 如果是单点登录进来的，啥也不去操作
      } else {
        // 只有在非登录页面的时候，才去判断是否4小时没操作而重新登录
        if (_path == '/login' || _path == '/check/sourceEnquiry' || _path == '/check/registration') {
          // 若在登录页面，啥也不去操作
        } else {
          if (_path == '/') {
            // 啥也不去操作
            console.warn('进入这里/')
          } else {
            console.warn('长时间未操作请重新登录')
            store.dispatch('user/logout')
            router.push('/login')
            Message.error('长时间未操作请重新登录')
          }
        }
      }
    }
    // 判断登录是否超过4小时
    if(!getLogoutFlag() || getLogoutFlag() === 'false') {
      setOperateTime(new Date().getTime())
      if(isRefreshing && !whiteList.includes(config.url)){
        // 拦截在刷新token时，同步发送的请求，待 token 刷新后再发起请求
        return new Promise(resolve => {
          // 将resolve放进队列，用一个函数形式来保存，等token刷新后直接执行
          requests.push(token => {
            config.headers['Authorization'] = 'Bearer ' + token
            config.headers['sysappid'] = sysAppId
            resolve(config)
          })
        })
      }else{
        const expiresTime = getExpiresTime()
        // 判断接口是否需要 token
        if(!whiteList.includes(config.url) && expiresTime < minExpTime) {
          isRefreshing = true
          // 令牌时间本地计算，未过期执行
          return expiresCalculation().then(async (e)=>{
            // console.log('expiresCalculation_res', e)
            // token 判断或token 刷新后继续请求
            let token = store.getters.token
            if (token) {
              // 已经刷新了token，将所有队列中的请求进行重试
              requests.forEach(cb => cb(token))
              requests = []
              config.headers['Authorization'] = 'Bearer ' + token
              config.headers['sysappid'] = sysAppId
            }
            isRefreshing = false
            return config
          }).catch((e)=>{
            // 请求更新token失败，重置拦截
            console.log('请求更新token失败，重置拦截', e)
            isRefreshing = false
            return Promise.reject(e || {
              status: 10001,
              message: '令牌已过期'
            })
          })
        }else{
          // 未过期，正常流程
          let token = store.getters.token
          if (token && config.url !== '/api/v1/mobileJwt/AccessTokenEncrypt') {
            config.headers['Authorization'] = 'Bearer ' + token
            config.headers['sysappid'] = sysAppId
          }
          return config
        }
      }
    }
  },
  error => {
    console.log(error)
    return Promise.reject(error)
  }
)

service.interceptors.response.use(
  response => {
    // 响应拦截
    // console.log(response.data)
    const status = response.status
    const code = response.data ? response.data.code : 0
    // 授权失败 401，访问令牌失效 403
    if((status === 401 && code === 10050) || ((status === 401 || status === 403) && code === 10040) ) {
      if(isRefreshing){
        // 拦截在刷新token时，同步发送的请求，待 token 刷新后再发起请求
        return new Promise(resolve => {
          // 将resolve放进队列，用一个函数形式来保存，等token刷新后直接执行
          requests.push(token => {
            config.headers['Authorization'] = 'Bearer ' + token
            config.headers['sysappid'] = sysAppId
            resolve(service(config))
          })
        })
      }else{
        isRefreshing = true
        // 令牌时间本地计算，未过期执行
        return expiresCalculation().then(()=>{
          // token 判断或token 刷新后继续请求
          let token = store.getters.token
          if (token) {
            // 已经刷新了token，将所有队列中的请求进行重试
            requests.forEach(cb => cb(token))
            requests = []
            config.headers['Authorization'] = 'Bearer ' + token
            config.headers['sysappid'] = sysAppId
          }
          isRefreshing = false
          return service(config)
        }).catch(()=>{
          // 请求更新token失败，重置拦截
          isRefreshing = false
          return Promise.reject()
        })
      }
    }
    setOperateTime(new Date().getTime())
    // 正常返回
    return response
  },
  error => {
    return Promise.resolve(error.response)
  }
)

export default service
